#ifndef _KCAPTURE_H
#define _KCAPTURE_H

#include <linux/types.h>
#include <linux/proc_fs.h>
 
extern struct proc_dir_entry proc_root;
#ifdef TEST
	#define debugn(s, s1, s2) _debugn(s, s1, s2);
	#define debug_printk(s,args...) 	if (isdebug) printk(s, ## args)
#else
	#define debugn(s, s1, s2)
	#define debug_printk(s,args...) 	if (isdebug) printk(s, ## args)
#endif


#ifdef DEBUG
#define DEBUGIP(x) debug_print_ip(x)
#define DEBUGIPDIR(s,d) debug_print_ip_dir(s,d)
#define DEBUGMAC(x) debug_print_mac(x)
#else
#define DEBUGIP(x)
#define DEBUGIPDIR(s,d)
#define DEBUGMAC(x)
#endif

#define ONE_SECOND HZ
#define RECOVERED (3*(ONE_SECOND))

#define INPUT_ETH "eth0"
#define OUTPUT_ETH "eth1"
#define FAKE_ETH "eth2"
#define MAX_SUBNET_NUM 10
#define TABLESIZE 65539// I set it 65539 to reduce the probability of hash conflict
#define LEFT_MAX  1000

enum {
	ARP = 0,
	IP = 1
};

enum {
    AUTO_PREV = 0,
    MANUAL_DROP = 1,
    MANUAL_ACCEPT = 2,
    WHITE_ACCEPT = 3,
    OUTSIDE_ACCEPT = 4,
};

enum {
	INTERFACE_IN = 1,
	INTERFACE_OUT = 2,
	INTERFACE_FAKE = 3,
};

struct send_pack_rate {
	unsigned long ipprev;//the jiffy value of last time
	unsigned long arpprev;//the jiffy value of last time
	unsigned long ipcount;
	unsigned long arpcount;
	unsigned long arprate;	//rate: arp rate, ip rate
	unsigned long iprate;//the avg rate at the jiffy
	int arp_infect;	//only from arp, may be infect
	int ip_infect;  //only from ip, may be infect
	unsigned long arp_low_rate_begin;
	unsigned long ip_low_rate_begin;
	unsigned int infected_times;
};

struct ip_rate_element {
	unsigned int saddr; //source ip addr of the packet
	unsigned char mac[6];//mac
	int interface;	//added by Yangrenbin 2006.4.19
	struct send_pack_rate rate;
	struct ip_rate_element * next;
};

struct ip_mac_table {
	unsigned int ipaddr;
	unsigned int netmask;
	unsigned char mac[6];
	unsigned int isolatetype;
	unsigned int status;
	char used;
};

enum {
	MANUAL_IP_TABLE,
	MANUAL_ISOLATE_TODO_TABLE,
	WHITE_TABLE,
};

void __debug_print_ip(unsigned int addr);
unsigned int arp_packet_capture(unsigned int hooknum,
						struct sk_buff **skb,
						const struct net_device *in,
						const struct net_device *out,
						int (*okfn)(struct sk_buff *));
int cast_char_to_int(char c);
unsigned int cast_str_to_int(char * str, int len);
int clear_ip_table(int type);
void clear_proc(void);
void close_fw_manual_ip_node(void);
void close_fw_manual_isolate_todo_node(void);
void close_packet_capture(void) ;
void close_proc_node(void) ;
void close_rate_proc(void);
void conflict_handler(int type, struct ip_rate_element * head,
					unsigned int ipaddr, unsigned char * mac,
					unsigned long now, int interface);
int count_new_rate(int type, struct ip_rate_element * entry,unsigned long now);
void debug_display_ktable(void);
void debug_print_ip(unsigned int addr);
void debug_print_ip_dir(unsigned int saddr, unsigned int daddr);
void debug_print_mac(unsigned char * mac);
void debug_print_string(char * str);
void _debugn(unsigned char *msg, char * pack, int len);
int get_fake_mac(char * eth, char * mac);
int hit_isolate(unsigned int src_ip);
void init_hash_table(void) ;
void init_manual_ip_tb_proc_file(void);
void init_manual_isolate_todo_proc_file(void);
void init_packet_capture(void);
void init_proc(void);
void init_proc_node(void);
void init_rate_proc(void);
int insert_ip_to_table(int tb_type, unsigned int ip, unsigned int netmask, char mac[6]);
unsigned int ip_packet_capture(unsigned int hooknum,
						struct sk_buff **skb,
						const struct net_device *in,
						const struct net_device *out,
						int (*okfn)(struct sk_buff *));
int is_same_subnet(unsigned int addr);
void kpcapture_cleanup(void);
int manual_close(struct inode *inode, struct file *file);
ssize_t manual_input(struct file *filp, const char *buff, size_t len, loff_t * off);
ssize_t manual_isolate_todo_input(struct file *filp, const char *buff, size_t len, loff_t * off);
int module_close(struct inode *inode, struct file *file);
ssize_t module_input(struct file *filp, const char *buff, size_t len, loff_t * off);
int module_open(struct inode *inode, struct file *file);
ssize_t module_output(struct file *filp,char *buffer,size_t length,loff_t * offset);

int fwtotal_close(struct inode *inode, struct file *file);
ssize_t fwtotal_write(struct file *filp, const char *buff, size_t len, loff_t * off);
int fwtotal_open(struct inode *inode, struct file *file);
ssize_t fwtotal_read(struct file *filp,char *buffer,size_t length,loff_t * offset);

ssize_t fwtable_read(struct file *file, char *buff, size_t length, loff_t *  off);
int module_permission(struct inode *inode, int op, struct nameidata *foo);
int policy(int infect, int type, int interface, unsigned int src_ip,
				unsigned char * src_mac,
				unsigned int dst_ip,
				unsigned char * dst_mac, int broadcast);

int fwtable_open(struct inode *inode, struct file *file);
int fwtable_close(struct inode *inode, struct file *file);
int power_10(int a,int b);
void reset_netmask(char * str,int len);
void reset_netnum(char * str,int len) ;
void reset_arp_rate(char * str,int len);
void reset_ip_rate(char * str,int len);
void reset_subnet(char * str,int len) ;
int send_fake_request(__be32 dst_ip, __be32 src_ip);
char * split_by_N(char * buf, char * src);
void time_out_destroy(void);
void debug_display_ip_table(int);
void dis_en_able_fw(char * str, int len);
int is_man_prev(unsigned int src_ip, char * mac);
void get_rtc_time(char *buf);
	
#endif
